package exception

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"time"
)

// BaseError 基础错误类型
type BaseError struct {
	Message string
}

func (e *BaseError) Error() string {
	return e.Message
}

// SystemError 系统级别异常，捕获需要终止程序
type SystemError struct {
	BaseError
}

// ProgramNormalError 正常程序异常，捕获不终止程序
type ProgramNormalError struct {
	BaseError
}

// NewSystemError 创建系统级别异常
func NewSystemError(message string) error {
	return &SystemError{
		BaseError: BaseError{Message: message},
	}
}

// NewSystemErrorFromError 根据 error 创建系统级别异常
func NewSystemErrorFromError(err error) error {
	return &SystemError{
		BaseError: BaseError{Message: err.Error()},
	}
}

// NewProgramError 创建正常程序异常
func NewProgramError(message string) error {
	return &ProgramNormalError{
		BaseError: BaseError{Message: message},
	}
}

// NewProgramErrorFromError 根据 error 创建正常程序异常
func NewProgramErrorFromError(err error) error {
	return &ProgramNormalError{
		BaseError: BaseError{Message: err.Error()},
	}
}

// LogError 记录错误日志
func LogError(err error) {
	log.Println(err.Error())
	switch err.(type) {
	case *SystemError:
		logToFile(err.Error(), "-system-error.log")
	case *ProgramNormalError:
		logToFile(err.Error(), "-program-error.log")
	default:
		logToFile(err.Error(), "-default-error.log")
	}
}

// logToFile 将日志写入文件
func logToFile(message, suffix string) {
	currentDate := time.Now().Format("2006-01-02")
	logDir := "logs"
	logFile := fmt.Sprintf("%s-logs%s", currentDate, suffix)

	// 创建日志目录
	if err := os.MkdirAll(logDir, os.ModePerm); err != nil {
		log.Fatalf("无法创建日志目录: %v", err)
	}

	// 创建或追加日志文件
	logPath := filepath.Join(logDir, logFile)
	file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("无法创建日志文件: %v", err)
	}
	defer file.Close()

	// 写入日志
	logger := log.New(file, "", log.LstdFlags|log.Lshortfile)
	logger.Println(message)
}

// InfoLogger 记录info级别的日志
var InfoLogger *log.Logger

// InitInfoLogger 初始化info级别的日志记录器
func InitInfoLogger() {
	currentDate := time.Now().Format("2006-01-02")
	logDir := "logs"
	logFile := fmt.Sprintf("%s-logs-info.log", currentDate)

	// 创建日志目录
	if err := os.MkdirAll(logDir, os.ModePerm); err != nil {
		log.Fatalf("无法创建日志目录: %v", err)
	}

	// 创建或追加日志文件
	logPath := filepath.Join(logDir, logFile)
	file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("无法创建日志文件: %v", err)
	}

	// 初始化info级别的日志记录器
	InfoLogger = log.New(file, "INFO: ", log.LstdFlags|log.Lshortfile)
}

// LogInfo 记录info级别的日志
func LogInfo(message string) {
	if InfoLogger == nil {
		InitInfoLogger()
	}
	InfoLogger.Println(message)
}
